#include <MenuButtons.h>
#include <QtCore/qpluginloader.h>
#include <QtGui/QMessageBox>


MenuButtons::MenuButtons(typeMapAppsConfiguratios *appConfigs, unsigned int nroTarjeta,
                         unsigned short nroSecuencia , int w , int h , QWidget* parent)
	: QWidget( parent )
{
	// inicializo variables
	m_NroTarjeta = nroTarjeta;
	m_NroSecuencia = nroSecuencia;
	m_AppsConfigMap = appConfigs;

	// estetica
	this->setFixedSize( w , h );
	this->setObjectName("MenuButtons");
	QString strStyle;
	strStyle.append("QWidget#MenuButtons { background-color: ");
    strStyle.append("QLinearGradient(x1:0,y1:0,x2:0,y2:0.5,stop: 0.5 #7db9e8, stop: 0 #1E5799,");
    strStyle.append(" stop: 0.5 #2989D8, stop: 0.51 #207cca, stop: 1 #7db9e8, stop: 0.899 #1E5799, ");
    strStyle.append("stop: 1 #1E5799 ) ; background-image: url(\"./Resources/BMLogoChubutIcon80.png\"); ");
    strStyle.append("background-position: center ; background-repeat:norepeat; }");
	this->setStyleSheet(strStyle);
	this->setWindowFlags(Qt::CustomizeWindowHint|Qt::FramelessWindowHint);

	// Imagen de estetica de la pantalla
	QLabel *labBetmaker = new QLabel("",this);
    //QPixmap pixmap("./Resources/BMBetmaker.png");
	QPixmap pixmap("./Resources/BMTituloChubut.png");
	labBetmaker->setPixmap(pixmap);
    labBetmaker->setMaximumHeight(pixmap.height());
    labBetmaker->setAlignment(Qt::AlignCenter);
	labBetmaker->setFixedHeight(150);

	// Layout de botones
	m_AppsButtonsLayout = new QGridLayout();
    m_AppsButtonsLayout->setSpacing(5);

	// Boton volver
	m_BackButton = new BMButton("",QIcon("./Resources/BMIcoVolver.png"));
	m_BackButton->setIconSize( QSize(125,50));
	m_BackButton->setFixedSize(150,75);
	connect( m_BackButton , SIGNAL ( clicked() ) , this , SLOT (slot_EmitCloseMenuButtons() ) );

	// Layout principal
	m_MainLayout = new QVBoxLayout();
	m_MainLayout->setAlignment(Qt::AlignTop|Qt::AlignHCenter);
	m_MainLayout->addWidget(labBetmaker);
	m_MainLayout->addLayout(m_AppsButtonsLayout);
	m_MainLayout->addWidget( m_BackButton , 0 , Qt::AlignBottom | Qt::AlignHCenter);
	m_MainLayout->setAlignment(Qt::AlignTop|Qt::AlignHCenter);
	this->setLayout(m_MainLayout);

	// creo grupo de botones
    m_ButtonsGroup = new QButtonGroup(this);

	// creo el Map de Interface
	m_InterfaceMap=new QMap<int, ApplicationsInterface*>();
	
	// Clase para referenciar al Plugin
	QPluginLoader *loadDll;
	
	// Creo una Clase tipo Object
	QObject *object;

	// creo una referencia de ApplicacionInterface, para utilizarla en el casteo
	// de la clase OBJECT, proposicionada pos QPLUGINLOADER
	ApplicationsInterface *appInterface;

	int row=0; //fila para el gridlayout
	
	typeMapAppsConfiguratios::iterator itMapConf;
	itMapConf = m_AppsConfigMap->begin();
	int count = 1;
	while ( itMapConf != m_AppsConfigMap->end() )
	{
		// crear boton
		QIcon icon( itMapConf.value()->m_PathImageButton );
		BMButton * btn = new BMButton("",icon); //Button without text (to use with ICONS)
		
		btn->setIconSize(QSize(245 , 95) );
		btn->setFixedSize( 250 , 100);

		// agregarlo al QGroupButtons
		m_ButtonsGroup->addButton(btn, itMapConf.key() );

		// agregarlo al layout de botones
		if( count %2 )
		{
			
			m_AppsButtonsLayout->addWidget( btn, row,0 );
		}
		else
		{
			m_AppsButtonsLayout->addWidget( btn, row,1 );
			row++;
		}

		
		try
		{
			// cargo como parametro el PATH de la DLL, proporcionada por el MAP de GAMECONFIGURACION
			loadDll=new QPluginLoader(itMapConf.value()->m_PathAppDllName);

			// agrego La DLL al Map, con la misma ID que la configuracion
			object=loadDll->instance();
			if(object)
			{
				appInterface= dynamic_cast<ApplicationsInterface*>(object);
				if(appInterface)
				{
					m_InterfaceMap->insert( itMapConf.key(), appInterface );
					// Conecto el juego con el slot que reemite la senial de envio de data al server
					connect ( appInterface, SIGNAL (signal_SendRequestToCommunication(int, QByteArray)) ,
                              this, SLOT (slot_ReemitRequestToCommunication(int,QByteArray)));
					connect ( appInterface , SIGNAL ( signal_GameClosed() ) , this , SLOT ( slot_CierraJuego() ) );

				}
				else
				{
					// TO DO: MOSTRAR MENSAJE DE ERROR AL NO ENCONTRAR LA INTERFAZ CORRECTA
				}
			}
			else
			{
				// TO DO: MOSTRAR MENSAJE DE ERROR AL NO ENCONTRAR LA INTERFAZ CORRECTA
				QMessageBox::critical(this,"Error instanciando dll de juego", loadDll->errorString() , QMessageBox::Close );
			}

			delete( loadDll );
		}
		catch( ... )
		{
			qDebug() << "WARNING: no se cargo la DLL correctamente" ;
		}
		
		itMapConf++;
		count++;
	}

	// Conectar los botones al SLOT que Ejecuta el Juego
	connect(m_ButtonsGroup, SIGNAL(buttonClicked(int)), this, SLOT(slot_MostrarJuego(int)));

	// Conectar Al SLOT que Cierra la Appication

}

MenuButtons::~MenuButtons()
{
	delete m_AppsButtonsLayout;
	delete m_BackButton;
	delete m_MainLayout;
	delete m_ButtonsGroup;
	delete m_InterfaceMap;
}

void MenuButtons::paintEvent(QPaintEvent *PE)
{
	QStyleOption o;
	o.initFrom(this);
	QPainter p(this);
	style()->drawPrimitive(QStyle::PE_Widget, &o, &p, this);
}

void MenuButtons::keyPressEvent(QKeyEvent *key)
{
	if(key->key()==Qt::Key_Escape)
		m_BackButton->click();
	else
		slot_reciveShortCut(key->key());
}

void MenuButtons::addButton( BMButton * bmb )
{

}

void MenuButtons::HandleResponse(QByteArray data)
{
	m_LastAppInUse->slot_HandleResponse( data );
}

void MenuButtons::slot_MostrarJuego( int id )
{
	// Consulto si el juego esta habilitado
	if ( m_AppsConfigMap->value(id)->m_ErrorCode == 0 )
	{
		// Referencio la Ultima Interfaz utilizada por la APLICACION PRINCIPAL
		m_LastAppInUse = m_InterfaceMap->value(id);
		
		m_JuegoInUse = m_LastAppInUse->GetInstance( id, m_NroTarjeta, m_NroSecuencia, m_AppsConfigMap->value(id) );

		m_JuegoInUse->move(this->x(), this->y());
		m_JuegoInUse->setFixedSize(this->width(),this->height());
		m_JuegoInUse->setFixedHeight(this->height());
	
		connect(m_JuegoInUse, SIGNAL(sign_confirApuesta(double)), this, SLOT(slot_reenvioImporteJugada(double)));
		connect(m_JuegoInUse, SIGNAL(sign_confirJuego(QList<QString>, QString, QString, double)),
                this, SLOT(slot_reenvioDatosApuestas(QList<QString>, QString, QString, double)) );
		connect(m_JuegoInUse, SIGNAL(signal_GameClosed()), this, SLOT(slot_CierraJuego()) );
		connect(m_JuegoInUse, SIGNAL(signal_ClearScreenClient()), this, SLOT( slot_limpiarPantallaCliente() ) );
		connect(m_JuegoInUse, SIGNAL(signal_ApuestaQuinielaPantalla(QList<QString>, QString, QList<QString>, double, bool) ), 
                this, SLOT(slot_reenvioQuinielaPantalla(QList<QString>, QString, QList<QString>, double, bool)) );
		connect(m_JuegoInUse, SIGNAL(signal_ChoiceJuegoPoceado(int)), this, SLOT(slot_reciveShortCut(int)) );
		//connecta la ultima apuesta, a un Atributo de clase de ESTA CLASE
		connect( m_JuegoInUse, SIGNAL(sign_ApuestaFinal(std::string)), this, SLOT(slot_recivoUltimaApestaPoceada(std::string)) );
		connect( m_JuegoInUse, SIGNAL(clicked()), this, SLOT(slot_respondSolicitudUltimaApuesta()) );
	
		m_JuegoInUse->show();
		m_JuegoInUse->setFocus();
        m_JuegoInUse->setWindowModality(Qt::WindowModal);
	}
	else
	{
		BMErrorMessage * em = new BMErrorMessage( m_AppsConfigMap->value(id)->m_ErrorDescription.toStdString().c_str() );
		em->show();
	}
}

void MenuButtons::slot_CierraJuego()
{
	this->show();
	m_JuegoInUse->hide();
	emit signal_GamedClosed();
}

void MenuButtons::slot_ReemitRequestToCommunication ( int idJuego  , QByteArray data ) 
{
	emit signal_SendRequestToCommunication( data );
}

void MenuButtons::slot_EmitCloseMenuButtons()
{
	emit signal_CloseMenuButtons();
}

void MenuButtons::slot_reenvioImporteJugada(double importeJugada)
{
	emit signal_EmitImporteJuego(importeJugada);
}

void MenuButtons::slot_reenvioDatosApuestas(QList<QString> numApuestas, QString nomJuego,
                                            QString modalidad, double importeTotal)
{
	emit signal_EmitDatosApuesta(numApuestas, nomJuego, modalidad, importeTotal);
}

void MenuButtons::slot_reenvioQuinielaPantalla(QList<QString> NumYpos, QString JuegoName, QList<QString> entes,
                                               double importeJuego, bool isRedoblona)
{
	emit signal_EmitQuinielaApuestaPantalla( NumYpos, JuegoName, entes, importeJuego, isRedoblona );
}

void MenuButtons::slot_limpiarPantallaCliente()
{
	emit signal_ClearScreen();
}

void MenuButtons::slot_reciveShortCut(int shortCut)
{
	switch(shortCut)
	{
		case LOTO_TRADICIONAL:
			slot_MostrarJuego(101);
			m_LastAppInUse->slot_shortCutPress(shortCut);
			break;
		case LOTO_DESQUITE:
			slot_MostrarJuego(101);
			m_LastAppInUse->slot_shortCutPress(shortCut);
			break;
		case LOTO_SOS:
			slot_MostrarJuego(101);
			m_LastAppInUse->slot_shortCutPress(shortCut);
			break;
		//QUINI6
		case QUINI6_TRADICIONAL:
			slot_MostrarJuego(102);
			m_LastAppInUse->slot_shortCutPress(shortCut);
			break;
		case QUINI6_REVANCHA:
			slot_MostrarJuego(102);
			m_LastAppInUse->slot_shortCutPress(shortCut);
			break;
		case QUINI6_SOS:
			slot_MostrarJuego(102);
			m_LastAppInUse->slot_shortCutPress(shortCut);
			break;
		//BRINCO
		case BRINCO_TRADICIONAL:
			slot_MostrarJuego(103);
			m_LastAppInUse->slot_shortCutPress(shortCut);
			break;
		
	}//fin de switch

	if(shortCut == ANULACIONES)
		slot_mostrarAnulacionReimprimir(true);

	if(shortCut == REIMPRIMIR)
		slot_mostrarAnulacionReimprimir(false);

}

void MenuButtons::slot_mostrarAnulacionReimprimir(bool isAnulacion)
{
	QString pathDLL;
	if(isAnulacion)
		pathDLL.append("./plugins/AnulacionDLL.dll");
	else
		pathDLL.append("./plugins/ReimprimirDLL.dll");

	QPluginLoader plugin(pathDLL, this);
	QObject* objectDLL = plugin.instance();
	
	//if(objectDLL)
	if(m_intefaceAnulacionReimp= dynamic_cast<ApplicationsInterface*>(objectDLL));
	{
		GameConfiguration* config=m_AppsConfigMap->value(100);
		
		//referencio ventana de ANULACION como la ultima Applicacion ejecutada.
		m_LastAppInUse=m_intefaceAnulacionReimp;

		m_appAnulaReimp=m_intefaceAnulacionReimp->GetInstance( m_NroTarjeta, m_NroSecuencia, config );
		m_appAnulaReimp->setFixedSize(this->size());
		m_appAnulaReimp->move(this->x(), this->y());
		connect( m_appAnulaReimp, SIGNAL(signal_SendDataToCommunication(QByteArray)), this, SLOT(slot_reenvioData(QByteArray)) );
		
	}
	m_appAnulaReimp->show();
}

void MenuButtons::slot_reenvioData(QByteArray data)
{
	
	emit signal_envioDataToServer(data);

}

void MenuButtons::slot_recivoUltimaApestaPoceada(std::string ultimaApuesta)
{
	m_DatosUltimaApuestas.clear();
	m_DatosUltimaApuestas=ultimaApuesta;
}
void MenuButtons::slot_respondSolicitudUltimaApuesta()
{
//	m_LastAppInUse->slot_reenvioSolicitudPoceado(m_DatosUltimaApuestas);

}